﻿/**	@file		shower_objs.h
 *	@date		(2011-07-30 00:03:49)/(2011-08-31 22:45:46)
 *-----------------------------------------------------------------------------
 *	@version	1.0.1.2
 *	@author		Nick Shallery	(nicknide@gmail.com)
 *	@copyright	YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.
 *-----------------------------------------------------------------------------
**/

#if			!defined(__LOLIX__LX_SHOWER__SHOWER_OBJS__NICK__K_IN_G__)
#define		__LOLIX__LX_SHOWER__SHOWER_OBJS__NICK__K_IN_G__

#if			!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)
	#include	"../lolix/lolix_macro.h"
#endif	//	!defined(__LOLIX__LOLI_X_MACRO__K_IN_G__)

#if			!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)
	#include	"../lolix/lolix_type.h"
#endif	//	!defined(__LOLIX__LOLIX_TYPE__K_IN_G__)

#if			!defined(__LOLIX__TOY__INVOKE_CAST__HPP__K_IN_G__)
	#include	"../lolix/toy/invoke_cast.hpp"
#endif	//	!defined(__LOLIX__TOY__INVOKE_CAST__HPP__K_IN_G__)

#if			!defined(__LOLIX__LXSHOWER__SHOWER_TYPES__NICK__K_IN_G__)
	#include	"./shower_types.h"
#endif	//	!defined(__LOLIX__LXSHOWER__SHOWER_TYPES__NICK__K_IN_G__)


namespace lolix{namespace pretty{class render_material;class render_mesh;class render_params;}}

namespace lxshower{
	class shower_body;
	class shower_model;
	class LOLIX_NO_VTABLE shower_room
		: public lolix::itf
	{
	public:
		LOLIX_DECLARE_ITF(lxshower::shower_room, lolix::itf, (0x26a357de, 0x9442184d, 0xb3bcba98, 0x8675d290));
		typedef lolix::toy::invoker_process<bool, false
			, lolix::toy::type_list<shower_bound_box const* /*area*/, lolix::lx_u64 /*area_id*/, void* /*usr_ptr*/>
		> _PROC_ENUM_SHOW_OBJS_CALL;

		//===========================================================================
		//	创建新对象
		//---------------------------------------------------------------------------
		//	@sobj	[ o]	: 新创建的对象
		//	@adjust	[i ] =0 : 新创建的对象坐标的参照对象
		//	@pos	[i ]	: 插入的坐标,adjust 为0, 则为绝对坐标, 否则为相对坐标
		//	@radio	[i ] =0	: 插入的包围球的半径
		//===========================================================================
		LOLIX_INTERFACE(bodies_count, lolix::size_type		, (void)const);
		LOLIX_INTERFACE(new_body	, lolix::LOLIX_RETNV	, (shower_body** sobj, shower_body* adjust, shower_space const* space, lolix::lx_f32 radio));
		LOLIX_INTERFACE(rmv_body	, lolix::LOLIX_RETNV	, (shower_body* sobj));
		LOLIX_INTERFACE(distance	, lolix::LOLIX_RETNV	, (shower_position* out_ptr, const shower_body* start, const shower_body* end));
		LOLIX_INTERFACE(enum_bodies	, lolix::LOLIX_RETNV	, (_PROC_ENUM_SHOW_OBJS_CALL obj_call, void* usrptr));
		LOLIX_INTERFACE(clr_showobj	, void					, (void));

		//===========================================================================
		//	ist_light
		//---------------------------------------------------------------------------
		//	@ptr		[i ]	: 需要插入的灯光
		//===========================================================================
		//LOLIX_INTERFACE(ist_light	, lolix::LOLIX_RETNV	, (light* ptr));

		//LOLIX_INTERFACE(rmv_light	, lolix::LOLIX_RETNV	, (light const* const ptr));
		//LOLIX_INTERFACE(clr_light	, void					, (void));

		//LOLIX_INTERFACE(ist_door	, lolix::LOLIX_RETNV	, (door*));
		//LOLIX_INTERFACE(rmv_door	, lolix::LOLIX_RETNV	, (door const*const));
		//LOLIX_INTERFACE(clr_door	, void					, (void));
		LOLIX_INTERFACE(get_bodies_by_area_id, lolix::LOLIX_RETNV	, (shower_body** out_array, size_type* io_array_size, lolix::lx_u64 area_id));

		template<typename _Tpa, typename _Tpb>
		LOLIX_INLINE_CALL lolix::LOLIX_RETNV enum_bodies(_Tpa* a, _Tpb b, void* usrptr){ return this->enum_bodies(_PROC_ENUM_SHOW_OBJS_CALL(a, b), usrptr); }
		template<typename _Tpa, typename _Tpb>
		LOLIX_INLINE_CALL lolix::LOLIX_RETNV enum_bodies(const _Tpa* a, _Tpb b, void* usrptr){ return this->enum_bodies(_PROC_ENUM_SHOW_OBJS_CALL(a, b), usrptr); }
#if			LOLIX_CFG__DEBUG
		template<size_type _Cnt>
		LOLIX_INLINE_CALL lolix::LOLIX_RETNV get_bodies_by_area_id(shower_body* (&out_array)[_Cnt], size_type* io_array_size, lolix::lx_u64 area_id)
		{
			LOLIX_ASSERT(*io_array_size <= _Cnt, L"数据越界错误");
			return this->get_bodies_by_area_id(out_array, io_array_size, area_id);
		}
#endif	//	LOLIX_CFG__DEBUG
		template<typename _Tlambda>
		LOLIX_INLINE_CALL lolix::LOLIX_RETNV enum_bodies(_Tlambda proc, void* usrptr)
		{
			struct lambda_help
			{
				LOLIX_INLINE_CALL lambda_help(_Tlambda proc):lm(proc){}
				_Tlambda lm;
				LOLIX_INLINE_CALL bool LOLIX_CALL invoke(shower_bound_box const* area, lolix::lx_u64 area_id, void* usr_ptr)
				{ return lm(area, area_id, usr_ptr); }
			}lhelp(proc);
			return this->enum_bodies(&lhelp, &lambda_help::invoke, usrptr);
		}
	};


	class LOLIX_NO_VTABLE shower_body
		: public lolix::itf
	{
	public:
		LOLIX_DECLARE_ITF(lxshower::shower_body, lolix::itf, (0x82f80369, 0xefa89944, 0xb8c1276a, 0xd2428b93));
		LOLIX_INTERFACE(set_udat	, void					, (void* ptr));
		LOLIX_INTERFACE(get_udat	, void*					, (void)const);

		LOLIX_INTERFACE(query_room	, lolix::LOLIX_RETNV	, (shower_room** out_ptr));
		LOLIX_INTERFACE(leave_room	, lolix::LOLIX_RETNV	, (void));

		LOLIX_INTERFACE(set_pos		, lolix::LOLIX_RETNV	, (shower_position const* pos));
		LOLIX_INTERFACE(get_pos		, lolix::LOLIX_RETNV	, (shower_position* pos)const);

		LOLIX_INTERFACE(set_scale	, lolix::LOLIX_RETNV	, (shower_size const* xyz));
		LOLIX_INTERFACE(get_scale	, lolix::LOLIX_RETNV	, (shower_size* xyz)const);

		LOLIX_INTERFACE(set_rotation, lolix::LOLIX_RETNV	, (shower_rotation const*));
		LOLIX_INTERFACE(get_rotation, lolix::LOLIX_RETNV	, (shower_rotation*)const);

		LOLIX_INTERFACE(get_boundball,lolix::LOLIX_RETNV	, (shower_bound_ball* out_ball)const);
	};

	class LOLIX_NO_VTABLE shower_model
		: public lolix::itf
	{
	public:
		LOLIX_DECLARE_ITF(lxshower::shower_model, lolix::itf, (0xa925cd9d, 0x79774542, 0xad7f5960, 0x03593a0b));
		LOLIX_INTERFACE(set_rdmate	, lolix::LOLIX_RETNV	, (lolix::pretty::render_material*));
		LOLIX_INTERFACE(set_rdmesh	, lolix::LOLIX_RETNV	, (lolix::pretty::render_mesh*));

		LOLIX_INTERFACE(ist_params	, lolix::LOLIX_RETNV	, (lolix::pretty::render_params*));
		LOLIX_INTERFACE(get_params	, lolix::LOLIX_RETNV	, (lolix::pretty::render_params**)const);
	};
}

#endif	//	!defined(__LOLIX__LX_SHOWER__SHOWER_OBJS__NICK__K_IN_G__)
